package com.xoa.global.timedTask;

import com.xoa.controller.work.WorkController;
import com.xoa.dao.WFE.WFEFlowRunMapper;
import com.xoa.dao.WFE.WFEFormTypeMapper;
import com.xoa.dao.common.SysParaMapper;
import com.xoa.dao.flowRunFeedback.FlowRunFeedbackMapper;
import com.xoa.dao.work.WorkMapper;
import com.xoa.dao.workflow.FlowProcessMapper;
import com.xoa.dao.workflow.FlowRunLogMapper;
import com.xoa.model.common.SysPara;
import com.xoa.model.document.DocumentModel;
import com.xoa.model.flowRunFeedback.FlowRunFeedback;
import com.xoa.model.sms.SmsBody;
import com.xoa.model.users.Users;
import com.xoa.model.workflow.*;
import com.xoa.service.WFE.WFELog.WFELog;
import com.xoa.service.WFE.WFERunner.WFEFlowRunInfo;
import com.xoa.service.WFE.WFERunner.WFERunner;
import com.xoa.service.document.DocumentSerivce;
import com.xoa.service.sms.SmsService;
import com.xoa.service.users.UsersService;
import com.xoa.util.*;
import com.xoa.util.common.StringUtils;
import org.jsoup.nodes.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Created by 刘建 on 2020/7/12 15:53
 * 定时任务-工作流超时提醒
 */
@Controller
public class WorkflowRemind {

    @Autowired
    private SysParaMapper sysParaMapper;
    @Autowired
    private FlowProcessMapper flowProcessMapper;
    @Autowired
    private WFEFlowRunMapper wfeFlowRunMapper;
    @Autowired
    private UsersService usersService;
    @Autowired
    private WFEFlowRunInfo wfeFlowRunInfo;
    @Autowired
    private WorkController workController;
    @Autowired
    private WFERunner wfeRunner;
    @Autowired
    private FlowRunLogMapper flowRunLogMapper;
    @Autowired
    private DocumentSerivce documentSerivce;
    @Autowired
    private SmsService smsService;
    @Autowired
    private FlowRunFeedbackMapper flowRunFeedbackMapper;
    @Autowired
    WFEFormTypeMapper wfeFormTypeMapper;
    @Autowired
    WorkMapper workMapper;

    //timeOutFlag为1时代表已超时。 timeOutFlag为2时代表即将超时。timeOutFlag为空或者0时代表未超时
    public Integer turnFlow() {
        //判断是否为超时工作并转交
        try {
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date dates = new Date(System.currentTimeMillis());
            long nd = 1000 * 24 * 60 * 60;//每天毫秒数
            long nh = 1000 * 60 * 60;//每小时毫秒数
            long nm = 1000 * 60;//每分钟毫秒数
            long ns = 1000;// 一秒钟的毫秒数
            List<FlowRunPrcs> list = wfeRunner.getWfeFlowRunPrcs().selectAllTime();
            for (FlowRunPrcs flowRunPrcs : list) {
                if (flowRunPrcs.getTimeOut() != null || !"".equals(flowRunPrcs.getTimeOut().trim())) {
                    String[] timeOutShuzu = flowRunPrcs.getTimeOut().split(",");
                    double timeOut = Double.parseDouble(timeOutShuzu[0]);
                    if (timeOutShuzu[1].endsWith("hour")) {
                        timeOut = timeOut;
                    } else if (timeOutShuzu[1].endsWith("day")) {
                        timeOut = timeOut * 24;
                    }
                    Date PrcsTime = new Date();
                    Date DeliverTime = new Date();
                    long diff = 0;
                    if (flowRunPrcs.getTimeOutType() == 0) {//超时计算从此步骤接收开始
                        PrcsTime = formatter.parse(flowRunPrcs.getPrcsTime());
                        if (flowRunPrcs.getPrcsFlag().endsWith("4") || flowRunPrcs.getPrcsFlag().endsWith("3")) {
                            if (flowRunPrcs.getDeliverTime() != null && flowRunPrcs.getDeliverTime() != "") {
                                if (PrcsTime.getTime() == (-621701856000l)) {//判断工作接收时间，默认是-621701856000l
                                    continue;
                                } else {
                                    diff = formatter.parse(flowRunPrcs.getDeliverTime()).getTime() - PrcsTime.getTime();
                                }
                            }
                        } else {
                            if (flowRunPrcs.getPrcsFlag().endsWith("1")) {
                                continue;
                            }
                            diff = dates.getTime() - PrcsTime.getTime(); // 获得两个时间的毫秒时间差异
                        }
                    } else if (flowRunPrcs.getTimeOutType() == 1) {//超时计算从上一步骤转交开始
                        if (flowRunPrcs.getPrcsId() > 1) {//判断是否为第一步骤
                            if (flowRunPrcs.getPrcsFlag().endsWith("4")) {//判断是否为已办结的工作
                                diff = formatter.parse(flowRunPrcs.getPrcsTime()).getTime() - formatter.parse(flowRunPrcs.getCreateTime()).getTime();
                            } else {
                                diff = dates.getTime() - formatter.parse(flowRunPrcs.getCreateTime()).getTime();
                            }
                        } else {//如果为第一步骤，超时计算从创建工作开始
                            if (flowRunPrcs.getPrcsFlag().endsWith("4")) {
                                diff = formatter.parse(flowRunPrcs.getDeliverTime()).getTime() - formatter.parse(flowRunPrcs.getPrcsTime()).getTime();
                            } else {
                                diff = dates.getTime() - formatter.parse(flowRunPrcs.getCreateTime()).getTime();
                            }
                        }
                    }
                    boolean bol = false;
                    SysPara myproject = sysParaMapper.querySysPara("MYPROJECT");
                    if (myproject != null && !StringUtils.checkNull(myproject.getParaValue())
                            && "dazu".equals(myproject.getParaValue())) {
                        bol = true;
                    }
                    if ((diff / ns) > (timeOut * 60 * 60)) {//如果为超时工作则将状态值改为已超时
                        if (bol) {
                            SmsBody smsBody = new SmsBody();
                            String remindUrl = "/workflow/work/workform?opflag=" + flowRunPrcs.getOpFlag() + "&flowId=" + flowRunPrcs.getFlowId() + "&flowStep=" + flowRunPrcs.getPrcsId() + "&runId=" + flowRunPrcs.getRunId() + "&prcsId=" + flowRunPrcs.getFlowPrcs();
                            String title = "";
                            String context = "";
                            DocumentModel documentModel = documentSerivce.checkRunId(flowRunPrcs.getRunId());
                            if (documentModel != null) {//如果是公文
                                title = bol ? flowRunPrcs.getRunName() : "您有超时公文需要签阅。";
                                context = "流水号：" + flowRunPrcs.getRunId() + "，公文文号：" + flowRunPrcs.getRunName();
                                remindUrl = "/workflow/work/workform?opflag=" + flowRunPrcs.getOpFlag() + "&flowId=" + flowRunPrcs.getFlowId() + "&flowStep=" + flowRunPrcs.getPrcsId() + "&tableName=" + documentModel.getTitle() + "&tabId=" + documentModel.getId() + "&runId=" + flowRunPrcs.getRunId() + "&prcsId=" + flowRunPrcs.getFlowPrcs() + "&isNomalType=false";
                                smsBody = new SmsBody("admin", "70", DateFormat.getTime(DateFormat.getCurrentTime()), remindUrl, title + context);
                            } else {//否则是工作流
                                title = bol ? flowRunPrcs.getRunName() : "您有超时工作需要办理。";
                                context = "流水号：" + flowRunPrcs.getRunId() + "，工作名称/文号：" + flowRunPrcs.getRunName();
                                smsBody = new SmsBody("admin", "7", DateFormat.getTime(DateFormat.getCurrentTime()), remindUrl, title + context);
                            }

                            smsBody.setRemindUrl(remindUrl);
                            smsBody.setToId(flowRunPrcs.getUserId());
                            smsBody.setBodyId(null);
                            smsService.saveSms(smsBody, flowRunPrcs.getUserId(), "1", "1", title, context, "xoa1001");//存储事物提醒并推送消息
                        } else {
                            if (flowRunPrcs.getUserId().equals("admin")) {
                                continue;
                            }
                            //转交当前的流程
                            FlowProcess process = flowProcessMapper.findProcess(flowRunPrcs.getFlowId(), flowRunPrcs.getFlowPrcs());
                            if (!StringUtils.checkNull(process.getTimeAutoTurn()) && process.getTimeAutoTurn().equals("1")) {
                                FlowRun flowRun = wfeFlowRunMapper.selectBuRunId(flowRunPrcs.getRunId());
                                DocumentModel documentModel = documentSerivce.checkRunId(flowRun.getRunId());
                                String tableName = "";
                                String tabId = "";
                                String smsContent = bol ? "" : "您有新的工作需要办理" + "，流水号：" + flowRun.getRunId() + "，工作名称/文号：" + flowRun.getRunName();
                                if (documentModel != null) {
                                    tableName = documentModel.getTitle();
                                    tabId = Integer.toString(documentModel.getId());
                                }
                                Users usersByuserId = usersService.getUsersByuserId(flowRunPrcs.getUserId());
                                //获取下一步骤的经办人
                                FlowProcess process2 = new FlowProcess();
                                FlowRunLog flowRunLog = new FlowRunLog();
                                flowRunLog.setIp("127.0.0.1");
                                flowRunLog.setRunId(flowRun.getRunId());
                                flowRunLog.setRunName(flowRun.getRunName());
                                flowRunLog.setFlowId(flowRun.getFlowId());
                                flowRunLog.setUserId("admin");
                                flowRunLog.setType("25");
                                flowRunLog.setTime(new Date());
                                flowRunLog.setPrcsId(flowRunPrcs.getPrcsId());
                                flowRunLog.setFlowPrcs(flowRunPrcs.getFlowPrcs());
                                if (process.getPrcsTo().split(",").length > 1) {//自动转交下一步有多条，，无法自动转交。记录日志
                                    flowRunLog.setContent(usersByuserId.getUserName() + "已超时办理，无法自动转交至下一步骤。自动转交下一步有多个步骤，无法自动转交！");
                                } else if (process.getPrcsTo().split(",").length == 1) {//跳转下一步为单节点
                                    process2 = flowProcessMapper.findProcess(flowRunPrcs.getFlowId(), Integer.parseInt(process.getPrcsTo().split(",")[0]));
                                    //获取智能选人数据
                                    AjaxJson branch = wfeFlowRunInfo.getBranch(flowRun.getFlowId(), flowRunPrcs.getFlowPrcs(), flowRun.getRunId(), usersByuserId);
                                    Map<Integer, Map<String, Object>> obj = (Map<Integer, Map<String, Object>>) branch.getObj();
                                    String[] split = process.getPrcsTo().split(",");
                                    Map<String, Object> step = obj.get(Integer.parseInt(split[0]));
                                    if (step != null) {
                                        List<Users> autoTypelist = (List<Users>) step.get("autoTypelist");
                                        if (autoTypelist.size() > 1) {//智能选人不止一个，无法自动转交。记录日志
                                            StringBuffer str = new StringBuffer();
                                            for (Users name : autoTypelist) {
                                                str.append(name + ",");
                                            }
                                            flowRunLog.setContent(usersByuserId.getUserName() + "已超时办理，无法自动转交至下一步骤，智能选人人员有多个，无法自动转交。候选人员：" + str.toString());
                                        } else if (autoTypelist.size() == 0) {//智能选人为空，无法自动转交。记录日志
                                            flowRunLog.setContent(usersByuserId.getUserName() + "已超时办理，无法自动转交至下一步骤，转交下一步骤智能选人为空，无法自动转交！");
                                        } else {//转交操作
                                            try {
                                                List<FlowFormType> allFlowForm = wfeFormTypeMapper.getFrombyFlowId(flowRun.getFlowId());
                                                FlowFormType flowFormType = allFlowForm.get(0);
                                                //获取表单信息
                                                Document document = HtmlUtil.getDom(flowFormType.getPrintModel());
                                                //可写字段串
                                                String prcsItem = process.getPrcsItem();
                                                String data = "";//需写入意见的data值
                                                if (!StringUtils.checkNull(prcsItem)) {
                                                    String[] split1 = prcsItem.split(",");
                                                    for (String str : split1) {
                                                        String dataValue = HtmlUtil.getDocumentName(document, str);
                                                        String documentDataType = HtmlUtil.getDocumentDataType(document, dataValue);
                                                        if (documentDataType.equals("sign")) {
                                                            data = dataValue;
                                                        }
                                                    }
                                                }
                                                if (!StringUtils.checkNull(data)) {//需向数据库写入默认意见
                                                    List<String> dataList = new ArrayList<>();
                                                    dataList.add(data);
                                                    //获取数据库存储的表单内容
                                                    Map<String, Object> dataValue1 = workMapper.getDataValue(dataList, flowRun.getRunId(), "flow_data_" + flowRun.getFlowId());
                                                    Date date = new Date();//签署意见获取当前时间
                                                    SimpleDateFormat dateFormat = new SimpleDateFormat("YYYY-MM-dd");//设置当前时间的格式，为年-月-日 
                                                    //拼成新的意见内容
                                                    String dataValue = dataValue1.get(data) + "<div id=\"eiderarea\" class=\"eiderarea\" user_id=\"admin\" prcs_id=\"1\">系统超时跳转，默认同意。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" +
                                                            usersByuserId.getUserName() + "&nbsp;&nbsp;" + dateFormat.format(date) + "<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong class=\"remove_sign\">x</strong></div>";
                                                    //更新sql
                                                    String setSql = data + "=" + "'" + dataValue + "'";
                                                    workMapper.updateDataValue(setSql, "flow_data_" + flowRun.getFlowId(), flowRun.getRunId());
                                                }
                                            } catch (Exception e) {
                                                flowRunLog.setContent(usersByuserId.getUserName() + "写入意见异常。");
                                            }
                                            workController.saveworks(flowRunPrcs.getRunId(), flowRun.getRunName(),
                                                    flowRunPrcs.getFlowId(), flowRunPrcs.getPrcsId(), flowRunPrcs.getPrcsFlag(),
                                                    process.getPrcsTo(), DateFormatUtils.formatDate(new Date()), autoTypelist.get(0).getUserName(), autoTypelist.get(0).getUserId()
                                                    , process.getPrcsId(), "",
                                                    ",", smsContent, "1,3,", tableName, tabId, Integer.toString(flowRunPrcs.getPrcsId()), flowRunPrcs.getUserId(), "0,");
                                            flowRunLog.setContent(usersByuserId.getUserName() + "已超时办理，系统自动转交至" + autoTypelist.get(0).getUserName() + "办理！");
                                        }
                                    } else {//step为空
                                        flowRunLog.setContent(usersByuserId.getUserName() + "已超时办理，无法自动转交至下一步骤。无法获取节点数据，无法自动转交！");
                                    }
                                } else {//下一步节点为空节点,无法自动转交。记录日志
                                    flowRunLog.setContent(usersByuserId.getUserName() + "已超时办理，无法自动转交至下一步骤。无下一步骤，无法自动转交！");
                                }
                                flowRunLogMapper.insertSelective(flowRunLog);
                            }
                        }
                        flowRunPrcs.setTimeOutFlag("1");
                        wfeRunner.getWfeFlowRunPrcs().upTimeOutFlagById(flowRunPrcs);
                    }
                    //cs要求提前2个小时发送事务提醒
                    if (myproject != null && !StringUtils.checkNull(myproject.getParaValue()) && "powerchina".equals(myproject.getParaValue())) {
                        if (diff / ns > ((timeOut * 60 * 60) - (2 * 60 * 60)) && ((timeOut * 60 * 60) - (2 * 60 * 60)) > 0) {//判断是否将要超时。（2小时）
                            if ((flowRunPrcs.getPrcsFlag().equals("1") || flowRunPrcs.getPrcsFlag().equals("2")) && !flowRunPrcs.getTimeOutFlag().equals("2")) {
                                SmsBody smsBody = new SmsBody();
                                String remindUrl = "/workflow/work/workform?opflag=" + flowRunPrcs.getOpFlag() + "&flowId=" + flowRunPrcs.getFlowId() + "&flowStep=" + flowRunPrcs.getPrcsId() + "&runId=" + flowRunPrcs.getRunId() + "&prcsId=" + flowRunPrcs.getFlowPrcs();
                                String title = "";
                                String context = "";
                                DocumentModel documentModel = documentSerivce.checkRunId(flowRunPrcs.getRunId());
                                if (documentModel != null) {//如果是公文
                                    title = "您有即将超时公文需要签阅。剩余时间还有2小时！";
                                    context = "流水号：" + flowRunPrcs.getRunId() + "，公文文号：" + flowRunPrcs.getRunName();
                                    remindUrl = "/workflow/work/workform?opflag=" + flowRunPrcs.getOpFlag() + "&flowId=" + flowRunPrcs.getFlowId() + "&flowStep=" + flowRunPrcs.getPrcsId() + "&tableName=" + documentModel.getTitle() + "&tabId=" + documentModel.getId() + "&runId=" + flowRunPrcs.getRunId() + "&prcsId=" + flowRunPrcs.getFlowPrcs() + "&isNomalType=false";
                                    smsBody = new SmsBody("admin", "70", DateFormat.getTime(DateFormat.getCurrentTime()), remindUrl, title + context);
                                } else {//否则是工作流
                                    title = "您有即将超时工作需要办理。剩余时间还有2小时！";
                                    context = "流水号：" + flowRunPrcs.getRunId() + "，工作名称/文号：" + flowRunPrcs.getRunName();
                                    smsBody = new SmsBody("admin", "7", DateFormat.getTime(DateFormat.getCurrentTime()), remindUrl, title + context);
                                }
                                smsBody.setRemindUrl(remindUrl);
                                smsBody.setToId(flowRunPrcs.getUserId());
                                smsBody.setBodyId(null);
                                smsService.saveSms(smsBody, flowRunPrcs.getUserId(), "1", "1", title, context, "xoa1001");//存储事物提醒并推送消息
                                flowRunPrcs.setTimeOutFlag("2");
                                wfeRunner.getWfeFlowRunPrcs().upTimeOutFlagById(flowRunPrcs);
                            }
                        }
                    }

                }
            }

        } catch (Exception e) {
            e.printStackTrace();

        }
        return 0;
    }

}
